import pandas as pd
import numpy as np
import re
import itertools
import matplotlib.pyplot as plt

# 载入情感分析后的数据
posdata = pd.read_csv("pos_result.csv", encoding = 'utf-8')
negdata = pd.read_csv("neg_result.csv", encoding = 'utf-8')

# 只保留nature为'n'的数据
posdata = posdata[posdata['nature'] == 'n']
negdata = negdata[negdata['nature'] == 'n']
from gensim import corpora, models
# 建立词典
pos_dict = corpora.Dictionary([[i] for i in posdata['word']])  # 正面
neg_dict = corpora.Dictionary([[i] for i in negdata['word']])  # 负面

# 建立语料库
pos_corpus = [pos_dict.doc2bow(j) for j in [[i] for i in posdata['word']]]  # 正面
neg_corpus = [neg_dict.doc2bow(j) for j in [[i] for i in negdata['word']]]   # 负面


def cos(vector1, vector2):
    """
    计算两个向量的余弦相似度函数
    :param vector1:
    :param vector2:
    :return: 返回两个向量的余弦相似度
    """
    dot_product = 0.0
    normA = 0.0
    normB = 0.0
    for a, b in zip(vector1, vector2):
        dot_product += a * b
        normA += a ** 2
        normB += b ** 2
    if normA == 0.0 or normB == 0.0:
        return (None)
    else:
        return (dot_product / ((normA * normB) ** 0.5))



def lda_k(x_corpus, x_dict):
    """
    主题数寻优
    :param x_corpus: 语料库
    :param x_dict: 词典
    :return: 返回主题数寻优结果
    """
    mean_similarity = []
    mean_similarity.append(1)

    for i in np.arange(2, 11):
        lda = models.LdaModel(x_corpus, num_topics=i, id2word=x_dict)  # LDA模型训练
        term = lda.show_topics(num_words=50)

        # 提取各主题词
        top_word = []
        for j in np.arange(i):
            top_word.append([''.join(re.findall('"(.*)"', word)) for word in term[j][1].split('+')])  # 列出所有词

        # 构造主题词列表
        mat = []
        for j in np.arange(i):
            top_w = top_word[j]
            mat.append(tuple([top_w.count(word) for word in set(sum(top_word, []))]))

        top_similarity = [0]
        for j in np.arange(i - 1):
            vector1 = mat[j]
            for k in np.arange(j + 1, i):
                vector2 = mat[k]
                top_similarity.append(cos(vector1, vector2))

        mean_similarity.append(sum(top_similarity) / (i * (i - 1) / 2))

    return mean_similarity

# 调用函数重新计算主题数寻优结果
pos_k = lda_k(pos_corpus, pos_dict)
neg_k = lda_k(neg_corpus, neg_dict)
print('正面评论主题的平均相似度', pos_k)
print('负面评论主题的平均相似度', neg_k)

# 绘制主题平均余弦相似度图形
# 解决中文显示问题
plt.rcParams['font.sans-serif']=['SimHei']
# 解决负号显示问题
plt.rcParams['axes.unicode_minus'] = False
fig = plt.figure(figsize=(10,8))

ax1 = fig.add_subplot(211)
ax1.plot(pos_k)
ax1.set_xlabel('正面评论LDA主题数寻优',fontsize=14)

plt.rcParams['font.sans-serif']=['SimHei']
# 解决负号显示问题
plt.rcParams['axes.unicode_minus'] = False
fig = plt.figure(figsize=(10,8))
ax2 = fig.add_subplot(212)
ax2.plot(neg_k)
ax2.set_xlabel('负面评论LDA主题数寻优', fontsize=14)
plt.show()

pos_lda = models.LdaModel(pos_corpus, num_topics = 2, id2word = pos_dict)
neg_lda = models.LdaModel(neg_corpus, num_topics = 2, id2word = neg_dict)
print("正面评论LDA模型训练结果：", pos_lda)
print("负面评论LDA模型训练结果：", neg_lda)
print("正面评论主题：", pos_lda.print_topics(num_words=10))
print("负面评论主题：", neg_lda.print_topics(num_words=10))
pos_lda.print_topics(num_words = 10)
neg_lda.print_topics(num_words = 10)